//<<<+++OPENSOURCE
//<<<+++OPENSOURCE_LICENSE
/**
 * @addtogroup FPDFAPI
 * @{
 */

/**
 * @file
 * @brief Tagged PDF support.
 *
 * The idea of tagging PDF is basically associating each of the rendered objects in 
 * page content, to a node in the document structure tree.
 */
//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FPDF_TAGGED_H_
#define _FPDF_TAGGED_H_
//<<<+++OPENSOURCE_MUST_END

class CPDF_StructTree;
class CPDF_StructElement;
struct CPDF_StructKid;

class CPDF_Document;
class CPDF_Page;

class IPDF_ReflowEngine;
class IPDF_ReflowedPage;

/** @brief PDF structure tree class. The tagged document structure tree. */
class CPDF_StructTree : public CFX_Object
{
public:
	/**
	 * Load the whole structure tree of a parsed PDF document.
	 *
	 * @param[in] pDoc		The input PDF document.
	 * @return The whole structure tree of the input PDF document.
	 */
	static CPDF_StructTree* LoadDoc(const CPDF_Document* pDoc);

	/**
	 * Load the partial structure tree for a page.
	 *
	 * @param[in] pDoc		The input PDF document.
	 * @param[in] pPageDict	The input page dictionary.
	 * @return The structure tree for the input page.
	 */
	static CPDF_StructTree* LoadPage(const CPDF_Document* pDoc, const CPDF_Dictionary* pPageDict);

	/** The destructor. */
	virtual ~CPDF_StructTree() {}

	/** Get the count of immediate children. */
	virtual int			CountTopElements() const = 0;
	/**
	 * Get an immediate child.
	 *
	 * @param[in] i			The zero-based child index.
	 * @return A structure element.
	 */
	virtual CPDF_StructElement*	GetTopElement(int i) const = 0;
};

/**
 * @brief PDF structure-kid structure.
 *
 * A structure element can have following types of kids:
 * -# Invalid kid (or kid outside of specified page if we are loading structure tree for a particular page);
 * -# Another structure element;
 * -# A marked content sequence in a page;
 * -# A marked content sequence in a content stream (like form or annotation);
 * -# A object in whole (like a form or an annotation).
 */
struct CPDF_StructKid
{
	enum {
		Invalid,			/**< Invalid. */
		Element,			/**< Structure element. */
		PageContent,		/**< Marked-content sequence of page's content stream. */
		StreamContent,		/**< Marked-content sequence of content stream of other like form/annotation etc. */
		Object				/**< An entire object, such as an XObject or an annotation. */ 
	} m_Type;

	/** The data of structure kid. */
	union {
		struct {
			/** The structure element pointer. can be NULL for page tree if this element is not sure to be related to a page. */
			CPDF_StructElement*	m_pElement;
			/** The structure element dictionary. */
			CPDF_Dictionary*	m_pDict;
		} m_Element;
		struct {
			/** The page object number. */
			FX_DWORD			m_PageObjNum;
			/** The content mark identifier. */
			FX_DWORD			m_ContentId;
		} m_PageContent;
		struct {
			/** The page object number. */
			FX_DWORD			m_PageObjNum;
			/** The content mark identifier. */
			FX_DWORD			m_ContentId;
			/** The object number referred. */
			FX_DWORD			m_RefObjNum;
		} m_StreamContent;
		struct {
			/** The page object number. */
			FX_DWORD			m_PageObjNum;
			/** The object number referred. */
			FX_DWORD			m_RefObjNum;
		} m_Object;
	};
};

/** @brief PDF structure element class. */
class CPDF_StructElement : public CFX_Object
{
public:
	/** Get the root structure tree. */
	virtual CPDF_StructTree*	GetTree() const = 0;
	/** Get the structure element type name. */
	virtual const CFX_ByteString&	GetType() const = 0;
	/** Get the parent structure element. */
	virtual CPDF_StructElement*	GetParent() const = 0;
	/** Get the element dictionary. */
	virtual CPDF_Dictionary *	GetDict() const = 0;

	/** Get the count of kids in the structure element. */
	virtual int					CountKids() const = 0;
	/**
	 * Get a kid.
	 *
	 * @param[in] index		The zero-based kid index in the structure element.
	 * @return A structure kid.
	 */
	virtual const CPDF_StructKid&	GetKid(int index) const = 0;
	/** Get the children array of this structure element. */
	virtual CFX_PtrArray*		GetObjectArray() = 0;

	/**
	 * General purpose attribute value retrieval.
	 *
	 * @param[in] owner				The owner of the attribute.
	 * @param[in] name				The name of the attribute.
	 * @param[in] bInheritable		Whether the attribute is inheritable.
	 * @return A PDF object of the attribute.
	 */
	virtual CPDF_Object*		GetAttr(FX_BSTR owner, FX_BSTR name, FX_BOOL bInheritable = FALSE, FX_FLOAT fLevel = 0.0F) = 0;

	/**
	 * @name Retrieving attribute value in particular type.
	 */
	/*@{*/

	/**
	 * Get a name attribute value.
	 *
	 * @param[in] owner				The owner of the attribute.
	 * @param[in] name				The name of the attribute.
	 * @param[in] default_value		The default value.
	 * @param[in] bInheritable		Whether the attribute is inheritable.
	 * @param[in] subindex			The sub-index field of the attribute.
	 * @return A name.
	 */
	virtual CFX_ByteString		GetName(FX_BSTR owner, FX_BSTR name, FX_BSTR default_value, FX_BOOL bInheritable = FALSE, int subindex = -1) = 0;
	/**
	 * Get a color attribute value.
	 *
	 * @param[in] owner				The owner of the attribute.
	 * @param[in] name				The name of the attribute.
	 * @param[in] default_value		The default value.
	 * @param[in] bInheritable		Whether the attribute is inheritable.
	 * @param[in] subindex			The sub-index field of the attribute.
	 * @return A #FX_ARGB color.
	 */
	virtual FX_ARGB				GetColor(FX_BSTR owner, FX_BSTR name, FX_ARGB default_value, FX_BOOL bInheritable = FALSE, int subindex = -1) = 0;
	/**
	 * Get a number attribute value.
	 *
	 * @param[in] owner				The owner of the attribute.
	 * @param[in] name				The name of the attribute.
	 * @param[in] default_value		The default value.
	 * @param[in] bInheritable		Whether the attribute is inheritable.
	 * @param[in] subindex			The sub-index field of the attribute.
	 * @return A number.
	 */
	virtual FX_FLOAT			GetNumber(FX_BSTR owner, FX_BSTR name, FX_FLOAT default_value, FX_BOOL bInheritable = FALSE, int subindex = -1) = 0;
	/**
	 * Get a integer attribute value.
	 *
	 * @param[in] owner				The owner of the attribute.
	 * @param[in] name				The name of the attribute.
	 * @param[in] default_value		The default value.
	 * @param[in] bInheritable		Whether the attribute is inheritable.
	 * @param[in] subindex			The sub-index field of the attribute.
	 * @return An integer.
	 */
	virtual int					GetInteger(FX_BSTR owner, FX_BSTR name, int default_value, FX_BOOL bInheritable = FALSE, int subindex = -1) = 0;

	/*@}*/
};
//<<<+++OPENSOURCE_MUST_BEGIN
#endif	// _FPDF_TAGGED_H_
//<<<+++OPENSOURCE_MUST_END

/** @} */



